#!/usr/bin/python2.6
import cPickle
import urllib
import simplejson
import atexit
import os
import readline
from voogleFuncs import *
from optionClass import *
import webbrowser as wb
import sys
from os import unlink

class searchHandler:

    global RESMAX
    searchURL = 'http://ajax.googleapis.com/ajax/services/search/web?'
    synonyms = {'quit' : ['q', 'quit', 'done', 'exit', 'x', 'bye'],
                'options' : ['options', 'opts', 'opt', 'o'],
                'search' : ['search', 'google', 'query', 'voogle'],
                'yes' : ['yes', 'y', 'affirmative', 'aye'],
                'help' : ['help']}

    
    
    def __init__(self, defaultOptions):

        # Load up raw_input history!  This is sooooo coool.
        
        histfile = os.path.join(os.getcwd(),'.vooglehist')
        try:
            readline.read_history_file(histfile)
        except IOError:
            pass
      
        atexit.register(readline.write_history_file, histfile)
        del histfile

        


        # Load up options history
        
        optfilename = os.path.join(os.getcwd(), '.voogleopts')
        try:
            optfile = open(optfilename)
            self.options = cPickle.load(optfile)
            optfile.close()
        except IOError, EOFError:
            self.options = defaultOptions
        atexit.register(self.dumpOptions)

    def help(self):
        helpfile = open('helpfile.txt')
        out(helpfile.read())
        helpfile.close()

    def dumpOptions(self):
        optfilename = os.path.join(os.getcwd(), '.voogleopts')
        try:
            optfile = open(optfilename, 'w')
            cPickle.dump(self.options, optfile)
            optfile.close()
        except IOError:
            out("Failed to save user options.", self.options)
        
    
    def setOptions(self):
        self.options.setOptionMenu()



    def run(self):
        out("Welcome to Voogle.  Type or say search to perform a Google search, options to set options, or help to get help", self.options)
        while True:
            try:
                input = getLowerInput()
            except EOFError:
                print
                out("Thank you for using Voogle!", self.options)
                exit(0)

            words = input.split()
            if input == '':
                pass            
            elif words[0] in self.synonyms['quit']:
                out("Thank you for using Voogle!", self.options)
                exit(0)
            elif words[0] in self.synonyms['options']:
                self.options.optionMenu()
            elif words[0] in self.synonyms['search']:
                self.searchMenu(words)
            elif words[0] in self.synonyms['help']:
                self.help()
            elif input != '':
                out(input, self.options)
            else:
                pass
    

    def searchMenu(self, words):
        if len(words) > 1:
            query = ' '.join(words[1:])
        else:
            query = getLowerInput('Enter query: ')
        self.search(query)



    def search(self, query):
        results = self.getNResults(query)
        if not results:
            out("No results!", self.options)
            return
        
        if self.options['lucky'] == 'true':
            wb.open(results[0]['url'])
        
        resultsServed = 0
        resToOpen = []
        start = 0
        quitNow = False
        
        while True:
            for i in range(self.options['results']):
                if (self.options['lucky'] == 'true' 
                        and start + i == 0):
                    continue

                resultsServed += 1
                if resultsServed >= RESMAX:
                    break
                res = results[start + i]

                urlFull = cleanHTML(res['url'])
                
                assert self.options['url'] in ['full', 'short']

                if self.options['url'] == 'full':
                    url = urlFull
                elif self.options['url'] == 'short':
                    url = cleanHTML(res['visibleUrl'])

                summary = cleanHTML(res['content'])
                title = cleanHTML(res['titleNoFormatting'])
                resdata = [title, summary, url]
                
                for datum in resdata:
                    out(datum, self.options)
                out("Open result? ")
                toOpen = getLowerInput()
                if toOpen in self.synonyms['yes']:
                    resToOpen.append(cleanHTML(urlFull))


                elif toOpen in self.synonyms['quit']:
                    quitNow = True
                    break
                

            if quitNow:
                break

            start += self.options['results']

            getMore = getLowerInput("More results? ")
            if getMore in self.synonyms['yes']:
                continue
            else:
                break

        for url in resToOpen:
            #print "Opening url:", url
            wb.open(url)
    
            


    def simpleSearch(self, query):
        results = getResults(query)

        for i in results:
            out(cleanHTML(i['titleNoFormatting']) + ": " + \
                         cleanHTML(i['url']), self.options)
        

    def getResults(self, query, start = 0, rsz = 8):
        
        querystring = urllib.urlencode({'q':query, 'start':start, 
                                        'rsz':rsz, 'v':'1.0'})

        url = self.searchURL + querystring
        search_results = urllib.urlopen(url)
        json = simplejson.loads(search_results.read())
        results = json['responseData']['results']
        return results


    def getNResults(self, query, N = RESMAX):
        #Default N
        if N == None or N <= 0:
            N = self.options['results']

        if type(N) != int:
            raise ValueError('getNResults() needs N an integer')
        elif N < 1 or N > RESMAX:
            raise ValueError('getNResults() needs N between 1 and ' +\
                                 str(RESMAX))
    
        start = 0
        
        results = []
        
        while N > 8:
            results += self.getResults(query, start, 8)
            start += 8
            N -= 8

        if N <= 8:
            results += self.getResults(query, start, N)
            start += N
            N -= N
        
        return results
    


def main():
    if 'wipe' in sys.argv:
        unlink('.voogleopts')
    
    s = searchHandler(defaultOptions)
    s.run()


if __name__ == '__main__':
    main()
